<?php
declare (strict_types=1);

namespace app\exam\logic\admin;

use app\admin\logic\system\Log;
use app\common\exception\LogicException;
use app\exam\model\admin\QuestionBankCategory as CategoryModel;

/**
 * 题库分类逻辑层
 */
class QuestionBankCategory extends CategoryModel
{
    /**
     * 分类数据
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param int $pid
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList($pid = 0)
    {
        $category = $this->where('pid', $pid)->select();
        if ($category) {
            foreach ($category as $cate) {
                $cate->hasChildren = $this->hasChildren($cate->id);
                // 如果有分类,题库数量 = 子分类总和
                if ($cate->hasChildren) {
                    $cate->num = $this->getSumNumByPid($cate->id);
                }
            }
        }
        return $category;
    }

    /**
     * 是否有子集
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param int $pid
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function hasChildren(int $pid = 0): bool
    {
        return $this->where('pid', $pid)->find() ? true : false;
    }

    /**
     * 创建分类
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param array $data
     * @return bool
     */
    public function createCategory(array $data)
    {
        // 验证数据
        $this->getValidate()->scene('add')->failException()->check($data);

        if (!$this->save($data)) {
            throw new LogicException('新建失败');
        }

        Log::write('新建题库分类【' . $data['title'] . '】', 'exam', 'create', true);
    }

    /**
     * 编辑分类
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param array $data
     * @return array|\think\Model
     */
    public function editCategory(array $data)
    {
        $category = $this->findOrFail($data['id']);
        // 验证数据
        $this->getValidate()->scene('edit')->failException()->check($data);

        $category->title = $data['title'];

        if (!$category->save()) {
            throw new LogicException("更新失败");
        }

        Log::write('更新题库分类【' . $data['title'] . '】', 'exam', 'update', true);

        return $category;
    }

    /**
     * 删除分类
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param $id
     * @return bool
     */
    public function deleteCategory($id)
    {
        $that = $this->findOrEmpty($id);
        if ($that->isEmpty()) {
            throw new LogicException('分类不存在');
        }
        // 是否有子级
        if ($this->hasChildren($that->id)) {
            throw new LogicException('存在子分类，不可删除');
        }
        if (!$that->delete()) {
            throw new LogicException("删除失败");
        }

        Log::write('删除题库分类【' . $that->title . '】', 'exam', 'delete', true);
    }

    /**
     * 无限极分类
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/29
     *
     * @param int $pid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function cascader($pid = 0)
    {
        $cate = $this->where('pid', $pid)->field('id as value,title as label')->select();
        if ($cate) {
            foreach ($cate as &$c) {
                $child = $this->cascader($c['value']);
                $child && $c['children'] = $child;
            }
            unset($c);
        }

        return $cate->toArray();
    }

    /**
     * 获取子类的题库数量总和
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/31
     *
     * @param int $pid
     * @return float
     */
    public function getSumNumByPid(int $pid)
    {
        return $this->where('pid', $pid)->sum('num');
    }

    /**
     * 解析题库名称
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/11/24
     *
     * @param $ids
     * @return string
     */
    public function parseTitle($ids)
    {
        $ids   = is_array($ids) ? $ids : explode(',', (string)$ids);
        $cates = $this->whereIn('id', $ids)->column('title');

        return implode('/', $cates);
    }

}
